package com.cloud.lawcase.api.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import com.cloud.lawcase.api.bean.LawCauseSearchCriteria;
import com.cloud.lawcase.api.constant.LawCaseConstant;
import com.cloud.lawcase.api.entity.TcDicLaw;
import com.cloud.lawcase.api.entity.TcDicLawCause;
import com.cloud.lawcase.api.entity.TcDicLawItem;
import com.cloud.lawcase.api.entity.TcLawClDetail;
import com.cloud.lawcase.api.entity.TcLawRelCauseBiz;
import com.cloud.lawcase.api.entity.TcLawRelCauseLawItem;
import com.cloud.lawcase.api.entity.TcRelPunishUnitFunc;
import com.cloud.lawcase.api.entity.TcRelPunishUnitLevel;
import com.cloud.lawcase.api.mapper.TcDicLawCauseMapper;
import com.cloud.lawcase.api.mapper.TcDicLawItemMapper;
import com.cloud.lawcase.api.mapper.TcDicLawMapper;
import com.cloud.lawcase.api.mapper.TcLawClDetailMapper;
import com.cloud.lawcase.api.mapper.TcLawRelCauseBizMapper;
import com.cloud.lawcase.api.mapper.TcLawRelCauseLawItemMapper;
import com.cloud.lawcase.api.mapper.TcRelPunishUnitFuncMapper;
import com.cloud.lawcase.api.mapper.TcRelPunishUnitLevelMapper;
import com.cloud.lawcase.api.service.LawItemService;
import com.cloud.lawcase.common.utils.ChineseHelper;
import com.cloud.lawcase.common.utils.RedisKeyHelper;
import com.cloud.lawcase.common.utils.WordHelper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

@Service
@Transactional
public class LawItemServiceImpl implements LawItemService {

	@Autowired
	private TcDicLawMapper tcDicLawMapper;
	@Autowired
	private TcDicLawItemMapper tcDicLawItemMapper;
	@Autowired
	private TcDicLawCauseMapper tcDicLawCauseMapper;
	@Autowired
	private TcLawRelCauseLawItemMapper tcLawRelCauseLawItemMapper;
	@Autowired
	private TcLawRelCauseBizMapper tcLawRelCauseBizMapper;
	@Autowired
	private TcRelPunishUnitFuncMapper tcRelPunishUnitFuncMapper;
	@Autowired
	private TcRelPunishUnitLevelMapper tcRelPunishUnitLevelMapper;
	@Autowired
	private TcLawClDetailMapper tcLawClDetailMapper;
	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Override
	public List<TcDicLawItem> loadLawItems(long id) {
		Example example = new Example(TcDicLawItem.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("lawId", id);
		example.orderBy("itemCode").asc();
		List<TcDicLawItem> items = tcDicLawItemMapper.selectByExample(example);
		for (TcDicLawItem item : items) {
			calculate(item);
		}
		return items;
	}

	@Override
	public List<TcDicLawItem> analysisFile(MultipartFile file) {
		List<TcDicLawItem> items = new ArrayList<TcDicLawItem>();
		InputStream in = null;
		try {
			in = file.getInputStream();
			List<String> contents = WordHelper.readWordParagraph(in);
			int currentZ = 0, currentJ = 0, currentT = 0, currentK = 0, currentX = 0, currentM = 0;
			long tempId = 0;
			for (String content : contents) {
				String temp = content;
				// 只取前7个字符进行判断，防止被全文误导：可以到第999条
				if (content.length() > 7)
					temp = content.substring(0, 7);
				// 解析段落是否为章
				String z = check(temp, "^第(.*?)章");
				if (null != z) {
					currentZ = ChineseHelper.chineseNumber2Int(z);
					currentJ = currentT = currentK = currentX = currentM = 0;
					content = content.replaceFirst("第(.*?)章", "").replaceAll("[　]", "").replace("\\s*|\t|\r|\n| ", "");
				}
				// 解析节
				String j = check(temp, "^第(.*?)节");
				if (null != j) {
					currentJ = ChineseHelper.chineseNumber2Int(j);
					currentT = currentK = currentX = currentM = 0;
					content = content.replaceFirst("第(.*?)节", "").replaceAll("[　]", "").replace("\\s*|\t|\r|\n| ", "");
				}
				// 解析段落是否为条
				String t = check(temp, "^第(.*?)条");
				if (null != t) {
					currentT = ChineseHelper.chineseNumber2Int(t);
					currentK = 1;
					currentX = currentM = 0;
					content = content.replaceFirst("第(.*?)条", "").replaceAll("[　]", "").replace("\\s*|\t|\r|\n| ", "");
				}
				// 解析段落是否为项
				String x = check(temp, "^（([一|二|三|四|五|六|七|八|九|十].*?)）"); // 项
				
				if (null != x) {
					currentX = ChineseHelper.chineseNumber2Int(x);
					content = content.replaceFirst("（([一|二|三|四|五|六|七|八|九|十].*?)）", "").replaceAll("[　]", "")
							.replace("\\s*|\t|\r|\n| ", "");
					currentM = 0;
				}
				// 解析目
				String m = check(temp, "^(\\d)\\."); //目
				if(null != m){
					currentM = Integer.valueOf(m);
					content = content.replaceFirst( "^(\\d)\\.", "").replaceAll("[ ]", "");
				}
				
				if (currentT > 0 && null == x && null == t && null == m) {
					currentK++;
					currentX = 0;
					content = content.replaceAll("[　]", "").replace("\\s*|\t|\r|\n| ", "");
				}
				
				if (currentZ > 0 || currentT > 0) {
					TcDicLawItem item = new TcDicLawItem();
					item.setItemId(++tempId);
					item.setItemContent(content);
					item.setChapterId(currentZ);
					item.setSectionId(currentJ);
					item.setArticleId(currentT);
					item.setParagraphId(currentK);
					item.setSubParagraphId(currentX);
					item.setEntryId(currentM);
					item.setItemName(calculate(item));
					items.add(item);
				}
			}

		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return items;
	}

	private String calculate(TcDicLawItem item) {
		StringBuilder sb = new StringBuilder("");
		if (item.getChapterId() > 0) {
			String chapterName = "第" + ChineseHelper.int2ChineseNumber(item.getChapterId()) + "章";
			// sb.append(chapterName);
			item.setItemTypeId(LawCaseConstant.ITEM_TYPE_CHAPTER);
			if (item.getChapterId() > 0 && item.getSectionId() == 0 && item.getArticleId() == 0
					&& item.getParagraphId() == 0 && item.getSubParagraphId() == 0) {
				item.setDisplayItemName(chapterName);
			}
		}
		if (item.getSectionId() > 0) {
			item.setItemTypeId(LawCaseConstant.ITEM_TYPE_SECTION);
			String sectionName = "第" + ChineseHelper.int2ChineseNumber(item.getSectionId()) + "节";
			if (item.getChapterId() > 0 && item.getSectionId() > 0 && item.getArticleId() == 0
					&& item.getParagraphId() == 0 && item.getSubParagraphId() == 0) {
				item.setDisplayItemName(sectionName);
			}
		}
		if (item.getArticleId() > 0) {
			String articalName = "第" + ChineseHelper.int2ChineseNumber(item.getArticleId()) + "条";
			sb.append(articalName);
			item.setItemTypeId(LawCaseConstant.ITEM_TYPE_ARTICLE);
			if (item.getParagraphId() == 1 && item.getSubParagraphId() == 0) {
				// 只有在第一款的情况下才显示条
				item.setDisplayItemName(articalName);
			}
		}
		if (item.getParagraphId() > 0) {
			sb.append("第").append(ChineseHelper.int2ChineseNumber(item.getParagraphId())).append("款");
			item.setItemTypeId(LawCaseConstant.ITEM_TYPE_PARAGRAPH);

		}
		if (item.getSubParagraphId() > 0) {
			sb.append("第").append(ChineseHelper.int2ChineseNumber(item.getSubParagraphId())).append("项");
			item.setItemTypeId(LawCaseConstant.ITEM_TYPE_SUB_PARAGRAPH);
			String subParagraphName = "（" + ChineseHelper.int2ChineseNumber(item.getSubParagraphId()) + "）";
			item.setDisplayItemName(subParagraphName);
		}
		if (item.getEntryId() > 0) {
			sb.append("第").append(ChineseHelper.int2ChineseNumber(item.getEntryId())).append("目");
			item.setItemTypeId(LawCaseConstant.ITEM_TYPE_ENTRY);
			item.setDisplayItemName(item.getEntryId() + ". ");
		}
		if (!StringUtils.isEmpty(item.getItemName())) {
			item.setItemName(item.getItemName().replaceAll("第(.*?)章", ""));
			item.setItemName(item.getItemName().replaceAll("第(.*?)节", ""));
		}
		return sb.toString();
	}

	private String check(String content, String sx) {
		Pattern pattern = Pattern.compile(sx);
		Matcher matcher = pattern.matcher(content);
		if (matcher.find()) {
			return matcher.group(1);
		}
		return null;
	}

	@Override
	public int importLawItem(TcDicLawItem[] lawItems, Long lawId) {
		TcDicLaw law = tcDicLawMapper.selectByPrimaryKey(lawId);
		// 删除条目
		Example example = new Example(TcDicLawItem.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("lawId", lawId);
		tcDicLawItemMapper.deleteByExample(example);
		// 删除事由
		Example lawCauseExample = new Example(TcDicLawCause.class);
		Example.Criteria lawCauseCriteria = lawCauseExample.createCriteria();
		lawCauseCriteria.andEqualTo("lawId", lawId);
		tcDicLawCauseMapper.deleteByExample(lawCauseExample);
		// 删除条目关联表
		Example relCauseLawItemExample = new Example(TcLawRelCauseLawItem.class);
		Example.Criteria relCauseLawItemCriteria = relCauseLawItemExample.createCriteria();
		relCauseLawItemCriteria.andEqualTo("lawId", lawId);
		tcLawRelCauseLawItemMapper.deleteByExample(relCauseLawItemExample);
		// 删除业务
		Example relCauseBizExample = new Example(TcLawRelCauseBiz.class);
		Example.Criteria relCauseBizCriteria = relCauseBizExample.createCriteria();
		relCauseBizCriteria.andEqualTo("lawId", lawId);
		tcLawRelCauseBizMapper.deleteByExample(relCauseBizExample);
		// 职能部门
		Example relPunishUnitFuncExample = new Example(TcRelPunishUnitFunc.class);
		Example.Criteria relPunishUnitFuncCriteria = relPunishUnitFuncExample.createCriteria();
		relPunishUnitFuncCriteria.andEqualTo("lawId", lawId);
		tcRelPunishUnitFuncMapper.deleteByExample(relPunishUnitFuncExample);
		// 职能级别
		Example relPunishUnitLevelExample = new Example(TcRelPunishUnitLevel.class);
		Example.Criteria relPunishUnitLevelCriteria = relPunishUnitLevelExample.createCriteria();
		relPunishUnitLevelCriteria.andEqualTo("lawId", lawId);
		tcRelPunishUnitLevelMapper.deleteByExample(relPunishUnitLevelExample);
		// 处罚阀值
		Example tcLawClDetailExample = new Example(TcLawClDetail.class);
		Example.Criteria tcLawClDetailCriteria = tcLawClDetailExample.createCriteria();
		tcLawClDetailCriteria.andEqualTo("lawId", lawId);
		tcLawClDetailMapper.deleteByExample(relPunishUnitLevelExample);

		for (TcDicLawItem item : lawItems) {
			item.setItemId(RedisKeyHelper.genereateKey(TcDicLawItem.class));
			item.setItemCode(law.getLawCode() + String.format("%02d", item.getChapterId())
					+ String.format("%02d", item.getSectionId()) + String.format("%03d", item.getArticleId())
					+ String.format("%02d", item.getParagraphId()) + String.format("%02d", item.getSubParagraphId())
					+ String.format("%02d", item.getEntryId()));
			item.setLawId(lawId);
		}
		final TcDicLawItem[] fItems = lawItems;
		jdbcTemplate.batchUpdate("insert into tc_dic_law_item(item_id, item_code, chapter_id, section_id, "
				+ "article_id, paragraph_id, sub_paragraph_id, entry_id, item_type_id, item_name, item_content, law_id)"
				+ " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", new BatchPreparedStatementSetter() {
					@Override
					public void setValues(PreparedStatement ps, int i) throws SQLException {
						TcDicLawItem it = fItems[i];
						ps.setLong(1, it.getItemId());
						ps.setString(2, it.getItemCode());
						ps.setInt(3, it.getChapterId());
						ps.setInt(4, it.getSectionId());
						ps.setInt(5, it.getArticleId());
						ps.setInt(6, it.getParagraphId());
						ps.setInt(7, it.getSubParagraphId());
						ps.setInt(8, it.getEntryId());
						ps.setInt(9, it.getItemTypeId());
						ps.setString(10, it.getItemName());
						ps.setString(11, it.getItemContent());
						ps.setLong(12, it.getLawId());
					}

					@Override
					public int getBatchSize() {
						return fItems.length;
					}
				});
		return lawItems.length;
	}

	@Override
	public PageInfo<TcDicLawItem> listLawItemPage(LawCauseSearchCriteria criteria) {
		PageInfo<TcDicLawItem> page = PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize())
				.doSelectPageInfo(() -> {
					tcDicLawItemMapper.listLawItemPage(criteria);
				});
		return page;
	}
}
